package paint;



    /**
     * A three dimensional vector in display coordinates
     * 
     * @author Dustin Striplin
     */
    public class Vector3D extends WorldVector{ 	
    	
    	/**
    	 * Create a vector from the given array
    	 * @param vect a vector array with 3 or more elements
    	 */
    	public Vector3D(double[] vect) {
    		this(vect[0], vect[1], vect[2]);
    	}
    	
    	/**
    	 * Creates a vector from world coordinates
    	 * @param x the x display coordinate
    	 * @param y the x display coordinate
    	 * @param z the x display coordinate
    	 */
    	public Vector3D(double x, double y, double z) {
    		vector = new double[3];
    		vector[X_INDEX] = x; 
    		vector[Y_INDEX] = y;
    		vector[Z_INDEX] =z;
    	}
    	
    	/**
    	 * Creates a 3D vector from the 4D vector by dividing x,y,and z by w
    	 * @param vect
    	 */
    	public Vector3D(Vector4D vect) {
    		//this(vect.vector[X_INDEX], vect.vector[Y_INDEX], vect.vector[Z_INDEX]);
    		this(vect.vector[X_INDEX]/vect.vector[W_INDEX], vect.vector[Y_INDEX]/vect.vector[W_INDEX], vect.vector[Z_INDEX]/vect.vector[W_INDEX]);
    	}
    	/**
    	 * @param a the first vector
    	 * @param b the vector that gets subtracted from a
    	 * @return a - b
    	 */
    	public static Vector3D subtract(Vector3D a, Vector3D b) {
    		double x = a.getX() - b.getX();
    		double y = a.getY() - b.getY();
    		double z = a.getZ() - b.getZ();	
    		return new Vector3D(x,y,z);
    	}
    	
    	/**
    	 * divide the given vector by the given scalar
    	 * @param a the vector to be divided
    	 * @param s the scalar to divide the vector by
    	 * @return
    	 */
    	public static Vector3D divide(Vector3D a, double s) {
    		double x = a.getX() / s;
    		double y = a.getY() / s;
    		double z = a.getZ() / s;
    		
    		return new Vector3D(x,y,z);
    	}
    	
    	/**
    	 * 
    	 * @param a
    	 * @param b
    	 * @return a x b
    	 */
    	public static Vector3D cross(Vector3D a, Vector3D b) {
    	    return new Vector3D( a.getY() * b.getZ() - a.getZ() * b.getY(),
    	            a.getZ() * b.getX() - a.getX() * b.getZ(),
    	            a.getX() * b.getY() - a.getY() * b.getX());
    	}
    	
    	/**
    	 * 
    	 * @param a
    	 * @param b
    	 * @return the product of a dot b
    	 */
    	public static double dot(Vector3D a, Vector3D b) {
    	    return a.getX()*b.getX() + a.getY()*b.getY() + a.getZ()*b.getZ();
    	}
    	
    	/**
    	 * 
    	 * @param a
    	 * @return the length of the vector a
    	 */
    	public static double length(Vector3D a) {
    		return Math.sqrt(dot(a,a) );
    	}
    	
    	/**
    	 * 
    	 * @param a
    	 * @return the normalized form of a
    	 */
    	public static Vector3D normalize(Vector3D u){
    		return divide(u,length(u));
    	}
    	
    	
    	@Override
    	public String toString() {
    		StringBuilder sb = new StringBuilder();
    		sb.append("x=");
    		sb.append(vector[X_INDEX]);
    		sb.append(", y=");
    		sb.append(vector[Y_INDEX]);
    		sb.append(", z=");
    		sb.append(vector[Z_INDEX]);
    		return sb.toString();
    	}
    }